package cn.heroes.weixin;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import net.sf.json.JSONArray;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.heroes.weixin.commons.Algorithm;
import cn.heroes.weixin.commons.HttpUtils;
import cn.heroes.weixin.commons.JSONUtils;
import cn.heroes.weixin.pojo.AccessToken;
import cn.heroes.weixin.pojo.ReturnCode;

/**
 * 各官方接口的实现
 * 
 * @author cq
 * 
 */
public class Utils {

	private static final Logger logger = LoggerFactory.getLogger(Utils.class);

	/**
	 * 验证URL有效性, 是否为服务器方发来的消息。
	 * 
	 * @param signature
	 * @param timestamp
	 * @param nonce
	 * @param echostr
	 * @return
	 */
	public static boolean verify(String signature, String timestamp,
			String nonce) {
		String[] ss = { Config.get().token, timestamp, nonce };
		Arrays.sort(ss);
		String result = Algorithm.encode("SHA1", ss[0] + ss[1] + ss[2]);
		if (result.equals(signature)) {
			return true;
		} else {
			logger.warn("URL校验失败[s: {}, t: {}, n: {}, e: {}, r: {}]",
					signature, timestamp, nonce, result);
			return false;
		}
	}

	/** Access Token凭证码过期时间时间的误差(保守)，单位：秒 */
	private static final int DEVIATION = 10;
	/** Access Token凭证码过期时间, 毫秒，since January 1, 1970, 00:00:00 GMT */
	private static long accessTokenExpireTime = 0L;
	/** 有效期内的Access Token凭证码 */
	private static String access_token = null;

	/**
	 * 获取当前有效的access token值， 即生产时间使用的Access_Token值.
	 * 
	 * @return
	 */
	public synchronized static String getAccessToken() {
		if (access_token == null
				|| new Date().getTime() > accessTokenExpireTime) {
			// 已过期,重新获取

			// 从服务器获取Access Token信息
			String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
					+ Config.get().appID + "&secret=" + Config.get().appsecret;
			String json = HttpUtils.get(url);

			// TODO error

			// 暂存Access Token信息
			AccessToken at = JSONUtils.toBean(json, AccessToken.class);
			access_token = at.access_token;
			accessTokenExpireTime = new Date().getTime()
					+ (at.expires_in - DEVIATION) * 1000;
		}
		return access_token;
	}

	/**
	 * 创建菜单
	 * 
	 * @param mbs
	 *            菜单Menu、按钮Button信息.
	 * @return true success, otherwise false.
	 * @see cn.heroes.weixin.pojo.Menu
	 * @see cn.heroes.weixin.pojo.Button
	 */
	public static boolean createMenu(List<Object> mbs) {
		// create menu request url
		String url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token="
				+ getAccessToken();

		// convert menus and buttons into json.
		String json = JSONArray.fromObject(mbs).toString();
		json = "{\"button\":" + json + "}";

		String result = HttpUtils.post(url, json);

		ReturnCode code = JSONUtils.toBean(result, ReturnCode.class);
		if (code.getErrcode() == 0) {
			logger.info("创建菜单成功{}.", json);
			return true;
		} else {
			logger.error("创建菜单失败{}, errcode: {}, errmsg: {}.", json,
					code.getErrcode(), code.getErrmsg());
			return false;
		}
	}

}
